/**
 * 
 * @Project le cOeur - Data Virtualization
 * @Date 08.12.2012
 * @Author Aebi Pascal, Kocher Marc
 * @School BFH-TI Biel, Bachelor Thesis
 *
 */

package main.api;

import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;

import main.api.http.MessageBody;
import main.api.http.MessageHeader;
import main.api.http.Method;
import main.api.http.Request;
import main.api.http.Version;
import main.api.setting.Config;

/**
 * This class is able to create different HTTP requests.
 */
public class RequestFactory {

	private SimpleDateFormat simpleDateFormat;

	/**
	 * Creates a request factory.
	 */
	public RequestFactory(){
		this.simpleDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH);
		this.simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
	}
	
	/**
	 * Creates a HTTP request corresponding to the given parameters.
	 * It adds automatically the predefined message headers "Host", "User-Agent", "Accept-Encoding", "Accept" and "Connection".
	 * 
	 * @param method The HTTP method.
	 * @param requestedURI The requested URI.
	 * @param version The HTTP version.
	 * @return The corresponding HTTP request.
	 */
	public Request createRequest(Method method, URI requestedURI, Version version){
		Request request = new Request(method, requestedURI, version);
		this.addDefaultMessageHeaders(request);
		return request;
	}
	
	/**
	 * Creates a HTTP request corresponding to the given parameters.
	 * It adds automatically the predefined message headers "Host", "User-Agent", "Accept-Encoding", "Accept" and "Connection".
	 * In addition corresponding to the message body the message headers "Content-Type" and "Content-Length" are added too.
	 * 
	 * @param method The HTTP method.
	 * @param requestedURI The requested URI.
	 * @param version The HTTP version.
	 * @param messageBody The message body.
	 * @return The corresponding HTTP request.
	 */
	public Request createRequest(Method method, URI requestedURI, Version version, MessageBody messageBody){
		Request request = new Request(method, requestedURI, version);
		this.addDefaultMessageHeaders(request);
		request.addMessageBody(messageBody);
		request.addMessageHeader(new MessageHeader("Content-Type", messageBody.getContentType().toString()));
		request.addMessageHeader(new MessageHeader("Content-Length", Integer.toString(messageBody.getLength())));
		return request;
	}
	
	/**
	 * Creates a HTTP request corresponding to the given parameters.
	 * It adds automatically the predefined message headers "Host", "User-Agent", "Accept-Encoding", "Accept" and "Connection".
	 * The given list of message headers is added after the predefined message headers.
	 * Thereby already existing headers will be overwritten.
	 * 
	 * @param method The HTTP method.
	 * @param requestedURI The requested URI.
	 * @param version The HTTP version.
	 * @param messageHeaders A list of message headers.
	 * @return The corresponding HTTP request.
	 */
	public Request createRequest(Method method, URI requestedURI, Version version, List<MessageHeader> messageHeaders){
		Request request = new Request(method, requestedURI, version);
		this.addDefaultMessageHeaders(request);
		request.addMessageHeaders(messageHeaders);
		return request;
	}
	
	/**
	 * Creates a HTTP request corresponding to the given parameters.
	 * It adds automatically the predefined message headers "Host", "User-Agent", "Accept-Encoding", "Accept" and "Connection".
	 * The given list of message headers is added after the predefined message headers.
	 * Thereby already existing headers will be overwritten.
	 * In the end corresponding to the message body the message headers "Content-Type" and "Content-Length" are added too.
	 * 
	 * @param method The HTTP method.
	 * @param requestedURI The requested URI.
	 * @param version The HTTP version.
	 * @param messageHeaders A list of message headers.
	 * @param messageBody The message body.
	 * @return The corresponding HTTP request.
	 */
	public Request createRequest(Method method, URI requestedURI, Version version, List<MessageHeader> messageHeaders, MessageBody messageBody){
		Request request = new Request(method, requestedURI, version);
		this.addDefaultMessageHeaders(request);
		request.addMessageHeaders(messageHeaders);
		request.addMessageBody(messageBody);
		request.addMessageHeader(new MessageHeader("Content-Type", messageBody.getContentType().toString()));
		request.addMessageHeader(new MessageHeader("Content-Length", Integer.toString(messageBody.getLength())));
		return request;
	}
	
	/**
	 * Adds the predefined default headers "Host", "User-Agent", "Accept-Encoding", "Accept" and "Connection" to the given HTTP request.
	 * 
	 * @param request The HTTP request.
	 */
	private void addDefaultMessageHeaders(Request request){
		request.addMessageHeader((new MessageHeader("Host", request.getRequestedURI().getHost())));
		request.addMessageHeader(new MessageHeader("User-Agent", Config.USER_AGENT));
		request.addMessageHeader(new MessageHeader("Accept-Encoding", "gzip, deflate"));
		request.addMessageHeader(new MessageHeader("Accept", Config.ACCEPT));
		request.addMessageHeader(new MessageHeader("Connection", "keep-alive"));
	}
	
}
